package pers.xiaojun.boot.module.system.controller.user;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import pers.xiaojun.boot.common.enums.CommonStatusEnum;
import pers.xiaojun.boot.common.enums.GenderEnum;
import pers.xiaojun.boot.common.pojo.CommonResult;
import pers.xiaojun.boot.common.pojo.PageResult;
import pers.xiaojun.boot.common.validation.group.CreateGroup;
import pers.xiaojun.boot.common.validation.group.UpdateGroup;
import pers.xiaojun.boot.excel.util.ExcelUtils;
import pers.xiaojun.boot.module.system.controller.user.vo.user.*;
import pers.xiaojun.boot.module.system.convert.UserConvert;
import pers.xiaojun.boot.module.system.dao.entity.dept.DeptDO;
import pers.xiaojun.boot.module.system.dao.entity.user.AdminUserDO;
import pers.xiaojun.boot.module.system.service.dept.DeptService;
import pers.xiaojun.boot.module.system.service.dept.UserPostService;
import pers.xiaojun.boot.module.system.service.user.UserService;
import pers.xiaojun.boot.web.core.annotation.AdminApi;

import java.io.IOException;
import java.util.Arrays;
import java.util.List;

@Tag(name = "用户")
@AdminApi
@RestController
@RequestMapping("/system/user")
@RequiredArgsConstructor
public class UserController {

    private final UserService userService;
    private final DeptService deptService;
    private final UserPostService userPostService;

    @Operation(summary = "创建用户")
    @PostMapping
    @PreAuthorize("@ss.hasPermission('system:user:create')")
    public CommonResult<?> createUser(@RequestBody @Validated(CreateGroup.class) UserSaveReqVO createVO) {
        return CommonResult.success(userService.saveUser(createVO).getId());
    }

    @Operation(summary = "更新用户")
    @PutMapping("/{id}")
    @PreAuthorize("@ss.hasPermission('system:user:update')")
    @Parameter(name = "id", description = "用户Id", required = true)
    public CommonResult<?> updateUser(@PathVariable("id") Long userId, @RequestBody @Validated(UpdateGroup.class) UserSaveReqVO updateVO) {
        updateVO.setId(userId);
        return CommonResult.success(userService.updateUser(updateVO).getId());
    }

    @Operation(summary = "更新用户状态")
    @PutMapping("/{id}/status")
    @PreAuthorize("@ss.hasPermission('system:user:update')")
    @Parameter(name = "id", description = "用户Id", required = true)
    public CommonResult<?> updateUserStatus(@PathVariable("id") Long userId, @RequestBody @Valid UserStatusUpdateReqVO updateStatusVO) {
        updateStatusVO.setId(userId);
        userService.updateUserStatus(updateStatusVO);
        return CommonResult.success();
    }

    @Operation(summary = "重置用户密码")
    @PutMapping("/{id}/password")
    @PreAuthorize("@ss.hasPermission('system:user:update')")
    @Parameter(name = "id", description = "用户Id", required = true)
    public CommonResult<?> updateUserPassword(@PathVariable("id") Long userId, @RequestBody @Valid UserStatusPasswordReqVO updatePasswordVO) {
        updatePasswordVO.setId(userId);
        userService.updateUserPassword(updatePasswordVO);
        return CommonResult.success();
    }

    @Operation(summary = "删除用户")
    @DeleteMapping("/{id}")
    @PreAuthorize("@ss.hasPermission('system:user:delete')")
    @Parameter(name = "id", description = "用户Id", required = true)
    public CommonResult<?> deleteUser(@PathVariable("id") Long userId) {
        userService.deleteUserById(userId);
        return CommonResult.success();
    }

    @Operation(summary = "删除一批用户")
    @DeleteMapping("/batch/{ids}")
    @PreAuthorize("@ss.hasPermission('system:user:delete')")
    @Parameter(name = "ids", description = "用户Id列表", required = true)
    public CommonResult<?> deleteUserBatch(@PathVariable("ids") List<Long> userIds) {
        userService.deleteUserByIds(userIds);
        return CommonResult.success();
    }

    @Operation(summary = "获取用户")
    @Parameter(name = "id", description = "用户Id", required = true)
    @GetMapping("/{id}")
    @PreAuthorize("@ss.hasPermission('system:user:query')")
    @Parameter(name = "id", description = "用户Id", required = true)
    public CommonResult<UserRespVO> getUser(@PathVariable("id") Long userId) {
        AdminUserDO user = userService.getUserById(userId);
        DeptDO dept = deptService.getById(user.getDeptId());
        List<Long> postIds = userPostService.listPostIdsByUserId(user.getId());
        return CommonResult.success(UserConvert.INSTANCE.toUserRespVO(user, dept, postIds));
    }

    @Operation(summary = "获取用户分页（条件查询）")
    @GetMapping("/page")
    @PreAuthorize("@ss.hasPermission('system:user:query')")
    public CommonResult<PageResult<UserRespVO>> getUserPage(@Valid UserPageReqVO pageVO) {
        Page<AdminUserDO> page = userService.listUsersPage(pageVO);
        List<DeptDO> depts = deptService.list();
        List<UserRespVO> userVOList = UserConvert.INSTANCE.toUserVOList(page.getRecords(), depts);
        return CommonResult.success(new PageResult<>(userVOList, page.getTotal()));
    }

    @Operation(summary = "获取用户简要信息列表")
    @GetMapping("/simple-list")
    @PreAuthorize("@ss.hasPermission('system:user:query')")
    public CommonResult<List<UserSimpleRespVO>> getSimpleUserList() {
        return CommonResult.success(UserConvert.INSTANCE.toSimpleUserList(userService.list(), deptService.list()));
    }

    @GetMapping("/import-template")
    @Operation(summary = "获取用户导入模板")
    public void getUserImportTemplate(HttpServletResponse response) throws IOException {
        List<UserImportExcelVO> list = Arrays.asList(
                UserImportExcelVO.builder()
                        .username("xiaojun")
                        .deptId(1L)
                        .email("junlanok@163.com")
                        .mobile("18860888888")
                        .nickname("XIAO鈞i")
                        .status(CommonStatusEnum.ENABLE.getStatus())
                        .sex(GenderEnum.MALE.getCode())
                        .build()
        );
        ExcelUtils.write(
                response,
                ExcelUtils.toXlsxFilename("用户导入模板"),
                "用户数据",
                UserImportExcelVO.class,
                list
        );
    }

    @GetMapping("/export-excel")
    @Operation(summary = "导出用户数据")
    @PreAuthorize("@ss.hasPermission('system:user:export')")
    public void exportUserExcel(HttpServletResponse response) throws IOException {
        List<AdminUserDO> users = userService.list();
        List<DeptDO> depts = deptService.list();
        ExcelUtils.write(
                response,
                ExcelUtils.toXlsxFilename("用户数据"),
                "用户数据",
                UserRespVO.class,
                UserConvert.INSTANCE.toUserVOList(users, depts)
        );
    }

    @PostMapping("/import")
    @Operation(summary = "导入用户数据")
    @PreAuthorize("@ss.hasPermission('system:user:import')")
    @Parameters({
            @Parameter(name = "file", description = "Excel文件", required = true),
            @Parameter(name = "isOverwrite", description = "是否覆盖旧数据（默认：false）")
    })
    public CommonResult<UserImportRespVO> importUserExcel(
            @RequestParam("file") MultipartFile file,
            @RequestParam(value = "isOverwrite", defaultValue = "false") Boolean isOverwrite) throws IOException {
        List<UserImportExcelVO> userImports = ExcelUtils.read(
                file.getInputStream(),
                UserImportExcelVO.class
        );
        return CommonResult.success(userService.importUsers(userImports, isOverwrite));
    }

}
